<?php

class UvmModel
{
    const USERNAME = 'uvm';
    const PASS     = 'app1e5ource';
    const HOSTNAME = '127.0.0.1';
    const SCHEMA   = 'uvm';
    
    
    
    private $_table = null;
    
    static $_pdo = null;
    
    public function __construct($table=null)
    {
        if (!is_null($table)) {
            $this->_table = $table;
        } else {
            throw new InvalidArgumentException('Model table not defined');
        }
    }
    
    /**
     * Gets database adapter (wired) 
     * 
     * @return PDO
     */
    public static function db()
    {
        if (!is_object(self::$_pdo)) {
            $dsn = 'mysql:host='.self::HOSTNAME.';dbname='.self::SCHEMA;
            $obj = new PDO($dsn, self::USERNAME, self::PASS);
            self::$_pdo = $obj;
        }
        return self::$_pdo;
    }
    
    public function get($id=null)
    {
        $pdo = self::db();
        $statement = "SELECT * FROM ".$this->_table." WHERE id = :id ";
        $q = $pdo->prepare($statement);
        $q->execute( array('id' => (is_numeric($id)) ? (int) $id : 0));
        $q->setFetchMode(PDO::FETCH_ASSOC);
        $arr = $q->fetch();
        return (is_array($arr)) ? $arr : array();
    }
    
    
    public function replaceIntoMappings($key, $value)
    {
        $pdo = self::db();
        $statement = "REPLACE INTO ".$this->_table." (xpath, value) VALUES (:xpth, :val)";
        $q = $pdo->prepare($statement);
        return $q->execute(array('xpth' => $key, 'val' => $value));
    }
    
    
    public function fetchRelations()
    {
        $pdo = self::db();
        $statement = "SELECT xpath, value FROM ".$this->_table;
        $q = self::db()->prepare($statement);
        $q->execute(); 
        $q->setFetchMode(PDO::FETCH_ASSOC);
        
        $out = array();
        // fetch
        while($r = $q->fetch()){
            $out[] = $r;
        }
        return $out;        
        
    }
    
    
    public function feed($collection=null, $filter=null)
    {
        $fltr = array();
        $in = '';
        
        if (is_string($collection) && strlen($collection)>0) {
            $collection = trim($collection);
            $ids        = array();
            $expl       = explode(',', $collection);
            foreach ($expl as $pos => $value) {
                $value = trim($value);
                if (is_numeric($value)) {
                   $ids[] = $value;
                }
            }    
            if (!empty($ids)) {
                $in = 'id IN( '.join(', ', $ids).' )';
            } else {
                throw new InvalidArgumentException('Empty or broken list of IDs');
            }
        }    
        
        if (is_array($filter)) {
            $fltr = array();
            
            if (isset($filter['like'])) {
                $fltr['like'] = $filter['like'];
            } else {
                foreach ($filter as $col => $value) {
                    $fltr[] = $col.' = '.$value;
                }
            }
        }
        
        if (strlen($in)>0) {
            $fltr[] = $in;
        }
        
        if (!empty($fltr)) {
            $merged = join(' AND ', $fltr);
        } else {
            throw new InvalidArgumentException('Ambiguos filter'); 
        }
        if (isset($fltr['like'])) {
            
            $pos   = strpos($fltr['like'], ':');
            $token = trim(substr($fltr['like'], strpos($fltr['like'], ':')+1, strlen($fltr['like'])));

            $statement = "SELECT * FROM ".$this->_table." WHERE title LIKE '{$token}%'
                            UNION
                          SELECT * FROM ".$this->_table." WHERE title LIKE '%{$token}%'
                          ";

        } else {
            $statement = "SELECT * FROM ".$this->_table." WHERE ".$merged;
        }
        
        //trap($statement);
        $q = self::db()->prepare($statement);
        $q->execute(); 
        $q->setFetchMode(PDO::FETCH_ASSOC);
        
        $out = array();
        // fetch
        while($r = $q->fetch()){
            $out[] = $r;
        }
        return $out;
    }
}
